//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "FontUtil.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
  : TForm(Owner)
{
}

//------------------------------//
//                              //
//------------------------------//
void __fastcall TForm1::OpenROMFile1Click(TObject *Sender)
{
  Open1->Title = "Open ROM File...";
  //---------------------//
  //                     //
  //---------------------//
  if ( Open1->Execute( ) )
  { //
    strcpy( romf, Open1->FileName.c_str( ) );
    rf = fopen( romf, "rb" );
    if ( !rf ){
      ShowMessage("Fatal Error: Could not open file!");
      return;
    }
    //
    _free( rom );
    _free( ram );
    //
    rom = (BYTE *)malloc( FSize = FileSize( rf ) );
    ram = (BYTE *)malloc( 0x10000 );
    //
    if ( !rom || !ram ){
      fclose( rf );
      ShowMessage( "Fatal Error: Could not allocate needed memory!" );
      Close( );
    }

    // Check for dumb header
    if ( FSize & 0x0200 ) {
      FSize -= 0x0200;
      fseek( rf, 0x0200, SEEK_SET );
    }
    // Read in the data
    memset( ram, 0, 0x10000 );
    fread( rom, 1, FSize, rf );
    fclose( rf );
    //
    ShowMessage("ROM File was loaded successfully!" );
    //
    Open1->FileName = ExtractFileDir( Open1->FileName );
    strcpy( dirc, Open1->FileName.c_str( ) );
  }
}


//------------------------------//
//                              //
//------------------------------//
void __fastcall TForm1::Exit1Click(TObject *Sender)
{
  Close( );
}


//------------------------------//
//                              //
//------------------------------//
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
  _free( rom );
  _free( ram );
}


//------------------------------//
//                              //
//------------------------------//
void __fastcall TForm1::DumpFont1Click(TObject *Sender)
{
  if ( !rom || !ram ){
    ShowMessage("Error: Must Load a ROM first." );
    return;
  }

  Save1->Title = "Select a File to Dump to...";
  if ( Save1->Execute( ) ) {
    strcpy( datf, Save1->FileName.c_str( ) );
    // Open it
    df = fopen( datf, "wb" );
    if ( !df ){
      ShowMessage("Error: Could not open Output File..." );
      fclose( df );
      return;
    }
  } else {
    ShowMessage("Error: No File was selected for dumping." );
    return;
  }

  //
  z = -1;
  while( ++z < 0x0400 )
  { // Amount of 8 - 16x16 Tiles
//    fseek( rf, Snes2Pc( 0x8C9C00 + (z << 1) ), SEEK_SET );
//    valu = readw( rf );
    valu = WGET( rom, Snes2Pc(0x8C9C00 + (z << 1)) );

    // Decode the font
    LRAM( 0x1A ) = 0x10F4;
    LRAM( 0x1D ) = 0x10B4;
    //
    WRAM( 0x10AA ) = 0x0000;
    WRAM( 0x10AC ) = 0x0000;
    WRAM( 0x10AE ) = 0x0004;
    //
    WRAM( 0x10B0 ) = 0x0000;
    LRAM( 0x30 )   = Snes2Pc( 0x8C0000 + valu );
    //
    reg.stack = 4;
    while( reg.stack > 0 )
    { //
      reg.y     = WRAM( 0x10AC );

      // Get to the font
//      fseek( rf, LRAM( 0x30 ) + reg.y, SEEK_SET );
//      ram[ 0x10B2 ] = fgetc( rf );
      ram[ 0x10B2 ] = rom[ LRAM( 0x30 ) + reg.y ];
      //
      reg.y++;
      WRAM( 0x10AC ) = reg.y;
      //
      reg.x = 8;
      while( reg.x > 0 )
      { //

        // BIT set??
        if ( ram[ 0x10B2 ] & 1 )
  			{ //
          reg.y = WRAM( 0x10AE );
//          fseek( rf, LRAM( 0x30 ) + reg.y, SEEK_SET );
//          ram[ 0x10B0 ] = fgetc( rf );
          ram[ 0x10B0 ] = rom[ LRAM( 0x30 ) + reg.y];
          reg.y++;
          WRAM( 0x10AE ) = reg.y;
        }

	// BIT clear
        reg.y = WRAM( 0x10AA );
        reg.a = ram[ 0x10B0 ];
        // Store the data
        ram[ WRAM(0x1A) + reg.y ] = reg.a;
        ram[ WRAM(0x1D) + reg.y ] = reg.a;
        reg.y++;
        WRAM( 0x10AA ) = reg.y;
        //
        reg.x--;

        ram[ 0x10B2 ] >>= 1;
      }// WEND

      reg.stack--;
    } // WEND - stack


    // Store the tile
/*/
    fwrite( &ram[ 0x10B4 + 0x00 ], 1, 0x20, df );
/*/
    fwrite( &ram[ 0x10B4 + 0x00 ], 1, 0x08, df );
    fwrite( &ram[ 0x10B4 + 0x10 ], 1, 0x08, df );
    fwrite( &ram[ 0x10B4 + 0x08 ], 1, 0x08, df );
    fwrite( &ram[ 0x10B4 + 0x18 ], 1, 0x08, df );
//*/
  }

  ShowMessage("Font Dump successfully!" );
  fcloseall( );
}


//------------------------------//
//                              //
//------------------------------//
void __fastcall TForm1::InsertFont1Click(TObject *Sender)
{
  LONG rom_posi,
       ram_posi,
       ptr_posi;
  WORD fptr[0x0400],
       ppos;
  BYTE bit_valu;
  BYTE data[64];
  BYTE null_bytes;


  if ( !rom ){
    ShowMessage("Error: Must Load a ROM first." );
    return;
  }

  Open1->Title    = "Open FONT File to Insert...";
  Open1->FileName = "";
  //---------------------//
  //                     //
  //---------------------//
  if ( Open1->Execute( ) )
  { //
    strcpy( datf, Open1->FileName.c_str( ) );
    df = fopen( datf, "rb" );
    if ( !df ){
      ShowMessage("Fatal Error: Could not open file!");
      return;
    }
    //
    _free( ram );
//    ram = (BYTE *)malloc( rom_posi = FileSize( df ) );
    rom_posi = FileSize( df );
    ram = (BYTE *)malloc(  ( rom_posi > 0x8000 ) ? rom_posi : 0x8000 );
    //
    if ( !ram ){
      fclose( df );
      ShowMessage( "Fatal Error: Could not allocate needed memory!" );
      Close( );
    }

    // Read in the data
//    fread( ram, 1, FileSize( df ), df );
    for ( long c = 0; c < rom_posi; c+=32 )
    {
//      fwrite( &ram[ 0x10B4 + 0x00 ], 1, 0x08, df );
//      fwrite( &ram[ 0x10B4 + 0x10 ], 1, 0x08, df );
//      fwrite( &ram[ 0x10B4 + 0x08 ], 1, 0x08, df );
//      fwrite( &ram[ 0x10B4 + 0x18 ], 1, 0x08, df );
      fread( &ram[ c + 0x00 ], 1, 0x08, df );
      fread( &ram[ c + 0x10 ], 1, 0x08, df );
      fread( &ram[ c + 0x08 ], 1, 0x08, df );
      fread( &ram[ c + 0x18 ], 1, 0x08, df );
    }
    fclose( df );
  }

  // Get to the Font data
  rom_posi = 0x8CA400;
  ptr_posi = Snes2Pc( 0x8C9C00 );
  ram_posi = 0;
  bit_valu = 0;
  ppos     = 0;
  //
  memset( fptr, 0, 0x0800 );
  memset( data, 0, 0x0020 );
  valu  = 0x0000;
  z     = -1;
  //-----------------------//
  // Encode the font       //
  //-----------------------//
  while( ++z < 0x0400 )
  { // Amount of 8 - 16x16 Tiles
    reg.stack = 4;
    // Start of data, first 4-BYTES = encoding
    reg.a      = 4;
    reg.x      = 0;
    null_bytes = 0;
    //------------------//
    //                  //
    //------------------//
    while( reg.stack > 0 )
    { //
      reg.y     = 0;
      while( reg.y++ < 8 )
      { //
        null_bytes |= ram[ ram_posi ];
        if ( ram[ ram_posi ] == valu )
        { // Clear BIT
          bit_valu >>= 1;
          ram_posi++;
        }
        else
        { // SET BIT
          valu            = ram[ ram_posi++ ];
          data[ reg.a++ ] = valu;
          bit_valu      >>= 1;
          bit_valu       |= 0x80;
        }
      }// WEND

      reg.stack--;
      data[ reg.x++ ] = bit_valu;
      bit_valu        = 0;
    } // WEND - stack

    // Store the tile
    if ( Optimize->Checked && !null_bytes && ppos ){
      // This points any "Blan Tiles" to the first
      // "Blank Tile"
      fptr[ ppos++ ] = fptr[ 0 ];
//      rom_posi      += reg.a;
    } else {
      fptr[ ppos++ ] = (rom_posi & 0xFFFF);
      memcpy( &rom[ Snes2Pc(rom_posi) ], data, reg.a );
      rom_posi += reg.a;
    }
  }// WEND

  //
  rf = fopen( romf, "wb+" );
  if ( !rf ){
    ShowMessage("Fatal Error: Could Not Open ROM File for writing..." );
    return;
  }
  // Store new data
  fwrite( rom, 1, FSize, rf );
  fseek( rf, ptr_posi, SEEK_SET );
  fwrite( fptr, 2, 0x0400, rf );
  fclose( rf );
  //
  ShowMessage("Data inserted to ROM!" );
}


//------------------------------//
//                              //
//------------------------------//
void __fastcall TForm1::OptimizeClick(TObject *Sender)
{
  Optimize->Checked ^= 1;
}


